﻿using System;
using System.Linq.Expressions;
using System.Reactive;
using System.Reactive.Linq;

namespace WcfDynamicProxy
{
    /// <summary>
    /// Фабрика запросов
    /// </summary>
    /// <typeparam name="TService"></typeparam>
    public class QueryFactory<TService> : IQueryFactory<TService>
    {
        private readonly IChannelFactory<TService> channelFactory;
        private readonly TaskManager taskManager;

        internal QueryFactory(IChannelFactory<TService> channelFactory, TaskManager taskManager)
        {
            this.channelFactory = channelFactory;
            this.taskManager = taskManager;
        }

        internal IChannelFactory<TService> ChannelFactory
        {
            get { return channelFactory; }
        }

        public IObservable<TResult> ExecuteQuery<TResult>(Expression<Func<TService, TResult>> call)
        {
            var channel = channelFactory.CreateChannel();

            return Query.Execute<TService, TResult>(channel, call, taskManager, () => DisposeChannel(channel));
        }

        public IObservable<Unit> ExecuteQuery(Expression<Action<TService>> call)
        {
            var channel = channelFactory.CreateChannel();

            return Query.Execute<TService>(channel, call, taskManager, () => DisposeChannel(channel));
        }

        private static void DisposeChannel(IAsyncChannel<TService> asyncChannel)
        {
            TraceLog("DisposeChannel");
            asyncChannel.Dispose();
        }

        private static void TraceLog(string message)
        {
            // TODO импортировать логер в конструкторе
            //System.Diagnostics.Debug.WriteLine("QueryFactory:" + message);
        }
    }
}